{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-10-23T01:47:38.823703Z",
     "start_time": "2020-10-23T01:47:37.948803Z"
    }
   },
   "outputs": [],
   "source": [
    "\n",
    "# download the dataset\n",
    "import requests\n",
    "\n",
    "\n",
    "r = requests.get('''https://www.csie.ntu.edu.tw/~cjlin/libsvmtools/datasets/regression/housing_scale''')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-10-23T01:47:59.324324Z",
     "start_time": "2020-10-23T01:47:58.610190Z"
    }
   },
   "outputs": [],
   "source": [
    "\n",
    "# load the dataset\n",
    "from sklearn.datasets import load_svmlight_file\n",
    "from io import BytesIO\n",
    "\n",
    "X, y = load_svmlight_file(f=BytesIO(r.content), n_features=13)\n",
    "X = X.toarray()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-10-23T01:48:17.515905Z",
     "start_time": "2020-10-23T01:48:17.510594Z"
    }
   },
   "outputs": [],
   "source": [
    "import numpy\n",
    "\n",
    "# preprocess\n",
    "n_samples, n_features = X.shape\n",
    "X = numpy.column_stack((X, numpy.ones((n_samples, 1))))\n",
    "y = y.reshape((-1, 1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-10-23T01:48:34.523547Z",
     "start_time": "2020-10-23T01:48:34.497494Z"
    }
   },
   "outputs": [],
   "source": [
    "\n",
    "# devide the dataset into traning set and validation set\n",
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.25)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-10-23T01:48:51.122739Z",
     "start_time": "2020-10-23T01:48:51.118911Z"
    }
   },
   "outputs": [],
   "source": [
    "penalty_factor = 0.5  # L2 regular term coefficients\n",
    "learning_rate = 0.0005\n",
    "max_epoch = 200\n",
    "\n",
    "losses_train = []\n",
    "losses_val = []"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-10-23T01:49:19.184464Z",
     "start_time": "2020-10-23T01:49:19.180783Z"
    }
   },
   "outputs": [],
   "source": [
    "# select different initializing method\n",
    "w = numpy.zeros((n_features + 1, 1))  # initialize with zeros\n",
    "# w = numpy.random.random((n_features + 1, 1))  # initialize with random numbers\n",
    "# w = numpy.random.normal(1, 1, size=(n_features + 1, 1))  # initialize with zero normal distribution"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-10-23T01:49:37.225925Z",
     "start_time": "2020-10-23T01:49:37.204404Z"
    }
   },
   "outputs": [],
   "source": [
    "for epoch in range(max_epoch):\n",
    "    diff = numpy.dot(X_train, w) - y_train\n",
    "    G = penalty_factor * w + numpy.dot(X_train.transpose(), diff)  # calculate the gradient\n",
    "    G = -G\n",
    "    w += learning_rate * G  # update the parameters\n",
    "\n",
    "    Y_predict = numpy.dot(X_train, w)  # predict under the train set\n",
    "    loss_train = numpy.average(numpy.abs(Y_predict - y_train))  # calculate the absolute differences\n",
    "    losses_train.append(loss_train)\n",
    "\n",
    "    Y_predict = numpy.dot(X_val, w)  # predict under the validation set\n",
    "    loss_val = numpy.average(numpy.abs(Y_predict - y_val))  # calculate the absolute differences\n",
    "    losses_val.append(loss_val)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-10-23T01:50:04.953435Z",
     "start_time": "2020-10-23T01:50:04.543467Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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jBmw665wyCEwbx5QVgZ//jN89hk8+mje5UmSJEmSVHRFCx9SSp8DYyNiw8KiAcA7lTa7Hzg0Mv2AySmlz4pVUx7ats3GmHz+efj97wsLv/c96NABHn8819okSZIkSaoPxb7axYnATRHxBtAb+GNEHBsRxxbWDwU+Aj4ErgSOL3I9ufjhD+HQQ+Hcc+HZZ4EWLWCHHeCJJ/IuTZIkSZK0HNq3bw/A+PHjOeCAA6rcZocddmDEiBE17ufCCy9kxowZ397efffdmTRp0nLXd9ZZZ3H++ecv936WV1HDh5TSqMJYDb1SSvuklL5JKV2eUrq8sD6llH6aUlo3pbRZSqnmo9GAXXoprL121v3im2+AnXaC0aPh44/zLk2SJEmStJxWW2017rzzzmW+f+XwYejQoXTq1KkOKisNxW75oIIOHbILXHz2GRxzDKSdds5W2PpBkiRJkkrCqaeeyj//+c9vb5911ln87W9/Y9q0aQwYMIAtttiCzTbbjPvuu2+x+44ZM4ZNN90UgJkzZzJ48GB69erFwQcfzMyZM7/d7rjjjqNv37707NmT3/3udwBcfPHFjB8/nh133JEdd9wRgB49evDll18C8Pe//51NN92UTTfdlAsvvPDbx9t44405+uij6dmzJ7vssssij1OVUaNG0a9fP3r16sW+++7LN9988+3jb7LJJvTq1YvBgwcD8Mwzz9C7d2969+5Nnz59mDp16rK8pN9qvlz31lLZaqts3IfTToOrd92IH6++ejbuw9FH512aJEmSJJWUn/8cRo2q23327g2F7+5VGjx4MD//+c85/vhsRIDbb7+dRx55hNatW3PPPfewwgor8OWXX9KvXz8GDRpERFUXcITLLruMtm3b8sYbb/DGG2+wxRYLr73whz/8gRVXXJH58+czYMAA3njjDU466ST+/ve/M2zYMLp06bLIvkaOHMk111zDSy+9REqJ73znO2y//fZ07tyZDz74gFtuuYUrr7ySgw46iLvuuoshQ4ZU+/wOPfRQLrnkErbffnvOPPNMzj77bC688ELOO+88Pv74Y1q1avVtV4/zzz+ff/zjH/Tv359p06bRunXrWr3G1bHlQz371a9gwAA46WfBZ9vuD08+CQsW5F2WJEmSJDV5ffr0YcKECYwfP57XX3+dzp07s+aaa5JS4je/+Q29evVip5124tNPP+WLL76odj/Dhw//NgTo1asXvXr1+nbd7bffzhZbbEGfPn14++23eeedytdlWNRzzz3HvvvuS7t27Wjfvj377bcfzz77LABrr702vXv3BmDLLbdkzJgx1e5n8uTJTJo0ie233x6Aww47jOHDh39b4yGHHMKNN95I8+ZZG4X+/fvzi1/8gosvvphJkyZ9u3xZ2fKhnjVrBuefD336wFNdDuKQry+G116DLbfMuzRJkiRJKhk1tVAopgMOOIA777yTzz///NsuCDfddBMTJ05k5MiRtGjRgh49ejBr1qwa91NVq4iPP/6Y888/n1deeYXOnTtz+OGHL3E/KaVq17Vq1erb+bKysiV2u6jOQw89xPDhw7n//vs599xzefvttznttNPYY489GDp0KP369eOJJ55go402Wqb9gy0fcrHZZtkYEC/M7J0tcNwHSZIkSSoJgwcP5tZbb+XOO+/89uoVkydPZuWVV6ZFixYMGzaMTz75pMZ9bLfddtx0000AvPXWW7zxxhsATJkyhXbt2tGxY0e++OILHn744W/v06FDhyrHVdhuu+249957mTFjBtOnT+eee+7he9/73lI/r44dO9K5c+dvW03ccMMNbL/99ixYsICxY8ey44478pe//IVJkyYxbdo0Ro8ezWabbcapp55K3759ee+995b6MSuy5UMOysqgXz94YVS7LIl4/HE49dS8y5IkSZKkJq9nz55MnTqV1VdfnW7dugFwyCGHsNdee9G3b1969+69xBYAxx13HEcccQS9evWid+/ebL311gBsvvnm9OnTh549e7LOOuvQv3//b+9zzDHHMHDgQLp168awYcO+Xb7FFltw+OGHf7uPo446ij59+tTYxaI61113HcceeywzZsxgnXXW4ZprrmH+/PkMGTKEyZMnk1Li5JNPplOnTpxxxhkMGzaMsrIyNtlkEwYOHLjUj1dR1NSEoxT17ds3Len6qA3BWWfBuefCpON+TYd/X5Bdf7NNm7zLkiRJkqTcvPvuu2y88cZ5l6Faqup4RcTIlFLfytva7SIn226bjTP50mr7wuzZ8NxzeZckSZIkSVJRGD7k5DvfgQh4YUZvaNEi63ohSZIkSVIjZPiQk44dYdNN4YURLbNmEA46KUmSJElqpAwfcrTttvCf/8CCATtnl9ucODHvkiRJkiQpVw1tXMKmammPk+FDjrbdFqZMgXfW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\n",
      "text/plain": [
       "<Figure size 1296x432 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "\n",
    "%matplotlib inline\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "plt.figure(figsize=(18, 6))\n",
    "plt.plot(losses_train, \"-\", color=\"r\", label=\"train loss\")\n",
    "plt.plot(losses_val, \"-\", color=\"b\", label=\"validation loss\")\n",
    "plt.xlabel(\"epoch\")\n",
    "plt.ylabel(\"loss\")\n",
    "plt.legend()\n",
    "plt.title(\"The graph of absolute diff value varing with the number of iterations\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
